package hr.ctg.domain.model;

import java.io.Serializable;
import java.sql.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.FilterDef;
import org.hibernate.annotations.ParamDef;

@Entity
@FilterDef(name = "periodPosjeteFilter", defaultCondition = "datum_posjete between :startDate and :endDate", parameters = {
		@ParamDef(name = "startDate", type = "date"),
		@ParamDef(name = "endDate", type = "date") })
@Filter(name = "periodPosjeteFilter")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
@Table(name = "posjet")
@NamedQueries( {
		@NamedQuery(name = "Posjet.findByObjektDatumPosjete", query = "select p from Posjet p where p.objekt.idObjekta = ? and p.datumPosjete = ?"),
		@NamedQuery(name = "Posjet.findByMjestoDatumPosjete", query = "select p from Posjet p where p.mjesto.idMjesta = ? and p.datumPosjete = ?"),
		@NamedQuery(name = "Posjet.findByOtokDatumPosjete", query = "select p from Posjet p where p.otok.idOtoka = ? and p.datumPosjete = ?"),
		/*
		 * @NamedQuery(name = "Posjet.findTopMjestaByPosjetMjesta", query =
		 * "select m from Posjet p join p.mjesto m group by m order by sum(p.brojPosjeta) desc"
		 * ),
		 */
		@NamedQuery(name = "Posjet.findTopMjestaByOcjena", query = "select m from Posjet p join p.mjesto m join m.dojamPosjetiteljas dpo group by m order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopOtociByPosjetMjesta", query = "select o from Posjet p join p.otok o group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopOtociByOcjena", query = "select o from Posjet p join p.otok o join o.dojamPosjetiteljas dpo group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByPosjetObjektaIdTipaObjekta", query = "select o from Posjet p join p.objekt o join o.tipObjekta to where to.idTipaObjekta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByOcjenaIdTipaObjekta", query = "select o from Posjet p join p.objekt o join o.dojamPosjetiteljas dpo join o.tipObjekta to where to.idTipaObjekta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopMjestaByOcjenaIdZupanije", query = "select m from Posjet p join p.mjesto m join m.objekts o join o.dojamPosjetiteljas dpo where m.zupanija.idZupanje = ? group by m order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopMjestaByOcjenaIdOtoka", query = "select m from Posjet p join p.mjesto m join m.objekts o join o.dojamPosjetiteljas dpo where m.otok.idOtoka = ? group by m order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopMjestaByPosjetMjestaIdZupanije", query = "select m from Posjet p join p.mjesto m where m.zupanija.idZupanje = ? group by m order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopMjestaByPosjetMjestaIdOtoka", query = "select m from Posjet p join p.mjesto m where m.otok.idOtoka = ? group by m order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopOtociByOcjenaIdZupanije", query = "select distinct o from Posjet p join p.otok o join o.mjestos m join o.dojamPosjetiteljas dpo where m.zupanija.idZupanje = ? group by m order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopOtociByPosjetOtokaIdZupanije", query = "select o from Posjet p join p.otok o join o.mjestos m where m.zupanija.idZupanje = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByOcjenaIdZupanijeIdTipaObjekta", query = "select o from Posjet p join p.objekt o join o.mjesto m join m.zupanija z join o.tipObjekta to join o.dojamPosjetiteljas dpo where to.idTipaObjekta = ? and z.idZupanje = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByPosjetObjektaIdZupanijeIdTipaObjekta", query = "select o from Posjet p join p.objekt o where o.tipObjekta.idTipaObjekta = ? and o.mjesto.zupanija.idZupanje = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByOcjenaIdOtokaIdTipaObjekta", query = "select o from Posjet p join p.objekt o join o.mjesto m join m.otok ot join o.tipObjekta to join o.dojamPosjetiteljas dpo where ot.idOtoka = ? and to.idTipaObjekta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByPosjetObjektaIdOtokaIdTipaObjekta", query = "select o from Posjet p join p.objekt o where o.mjesto.otok.idOtoka = ? and o.tipObjekta.idTipaObjekta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByOcjenaIdMjestaIdTipaObjekta", query = "select o from Posjet p join p.objekt o join o.mjesto m join o.tipObjekta to join o.dojamPosjetiteljas dpo where m.idMjesta = ? and to.idTipaObjekta = ? group by o order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findTopObjektiByPosjetObjektaIdMjestaIdTipaObjekta", query = "select o from Posjet p join p.objekt o where o.mjesto.idMjesta = ? and o.tipObjekta.idTipaObjekta = ? group by o order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByPosjetiIdOtoka", query = "select count(o) from Posjet p join p.objekt o join o.mjesto m join o.posjetObjektas p where m.otok.idOtoka= ?"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByOcjenaIdOtoka", query = "select count(o) from Posjet p join p.objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.otok.idOtoka = ?"),
		@NamedQuery(name = "Posjet.findTopMjestaByPosjetObjektaIdTipaObjekta", query = "select m from Posjet p join p.mjesto m join m.objekts o join o.posjetObjektas p where o.tipObjekta.idTipaObjekta = ? group by m order by sum(p.brojPosjeta) desc"),
		@NamedQuery(name = "Posjet.findTopMjestaByOcjenaIdTipaObjekta", query = "select m from Posjet p join p.mjesto m join m.objekts o join o.dojamPosjetiteljas dpo where o.tipObjekta.idTipaObjekta = ? group by m order by avg(dpo.ocjena) desc"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByPosjeti", query = "select count(o) from Posjet p join p.objekt o join o.posjetObjektas p"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByOcjena", query = "select count(o) from Posjet p join p.objekt o join o.dojamPosjetiteljas dpo"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByOcjenaIdZupanije", query = "select count(o) from Posjet p join p.objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.zupanija.idZupanje = ?"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByPosjetiIdZupanije", query = "select count(o) from Posjet p join p.objekt o join o.mjesto m join o.posjetObjektas p where m.zupanija.idZupanje = ?"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByOcjenaIdMjesta", query = "select count(o) from Posjet p join p.objekt o join o.mjesto m join o.dojamPosjetiteljas dpo where m.idMjesta = ?"),
		@NamedQuery(name = "Posjet.findCountTopObjektiByPosjetiIdMjesta", query = "select count(o) from Posjet p join p.objekt o join o.mjesto m join o.posjetObjektas p where m.idMjesta = ?") })
// @NamedNativeQueries({@NamedNativeQuery(name="Posjet.nFindTopMjestaByPosjetMjesta",query="select mjesto1_.id_mjesta as id1_4_, mjesto1_.grad as grad4_, mjesto1_.latituda as latituda4_, mjesto1_.longituda as longituda4_, mjesto1_.naziv as naziv4_, mjesto1_.opis as opis4_, mjesto1_.id_otoka as id10_4_, mjesto1_.panoramio as panoramio4_, mjesto1_.id_poste as id11_4_, mjesto1_.www as www4_, mjesto1_.zoom as zoom4_, mjesto1_.id_zupanije as id12_4_ from (SELECT id_mjesta FROM posjet where id_mjesta is not null and datum_posjete BETWEEN DATE_SUB(CURRENT_DATE,INTERVAL 1 MONTH) AND CURRENT_DATE group by id_mjesta order by sum(broj_posjeta) desc limit ?1) posjet0_  inner join mjesto mjesto1_ on posjet0_.id_mjesta=mjesto1_.id_mjesta")})
public class Posjet implements Serializable {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id_posjeta_objekta")
	private int idPosjetaObjekta;

	@Column(name = "broj_posjeta")
	private int brojPosjeta;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_objekta")
	private Objekt objekt;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_otoka")
	private Otok otok;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "id_mjesta")
	private Mjesto mjesto;

	@Column(name = "datum_posjete")
	private Date datumPosjete;

	private static final long serialVersionUID = 1L;

	public Posjet() {
		super();
	}

	public int getIdPosjetaObjekta() {
		return idPosjetaObjekta;
	}

	public void setIdPosjetaObjekta(final int idPosjetaObjekta) {
		this.idPosjetaObjekta = idPosjetaObjekta;
	}

	public int getBrojPosjeta() {
		return brojPosjeta;
	}

	public void setBrojPosjeta(final int brojPosjeta) {
		this.brojPosjeta = brojPosjeta;
	}

	public Date getDatumPosjete() {
		return datumPosjete;
	}

	public void setDatumPosjete(final Date datumPosjete) {
		this.datumPosjete = datumPosjete;
	}

	public Objekt getObjekt() {
		return objekt;
	}

	public void setObjekt(final Objekt objekt) {
		this.objekt = objekt;
	}

	public Mjesto getMjesto() {
		return mjesto;
	}

	public void setMjesto(final Mjesto mjesto) {
		this.mjesto = mjesto;
	}

	public Otok getOtok() {
		return otok;
	}

	public void setOtok(final Otok otok) {
		this.otok = otok;
	}

}
